package com.feng.service.impl;

import com.feng.dao.ProductDao;
import com.feng.dto.ProductDto;
import com.feng.dto.UserDto;
import com.feng.entity.User;
import com.feng.service.ESService;
import com.feng.service.ProductService;
import com.feng.util.BeanCopyUtil;
import com.feng.util.StringUtil;
import com.feng.vo.FrontPageVo;
import com.feng.vo.PageVo;
import com.feng.vo.ProductVo;
import com.feng.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: 丰
 * @date: 2022/12/30 10:44
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductDao productDao;

    @Autowired
    private ESService<ProductDto> esService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public ResultVo<List<ProductDto>> selectAll(PageVo pageVo) {
        StringUtil.checkPageVo(pageVo);
        try {
            return esService.getDoc(pageVo, "product_doc", ProductDto.class);
        } catch (IOException e) {
            // 查出数据封装
            List<ProductDto> productList = productDao.selectAll(pageVo);
            ResultVo<List<ProductDto>> resultVo = ResultVo.failed();
            if (productList != null){
                resultVo = ResultVo.success(productList);
                // 查出count
                resultVo.count(productDao.count(pageVo)).code(0);
            }
            return resultVo;
        }
    }

    public List<ProductDto> selectAll() {
        // 如果为空，就设置为null
        PageVo pageVo = new PageVo();
        pageVo.setPage(1);
        pageVo.setLimit(10000);
        return productDao.selectAll(pageVo);
    }

    @Override
    public ResultVo<Integer> add(ProductVo productVo) {
        // 获取时间
        String date = StringUtil.getStringDate();
        productVo.setCreateTime(date);
        productVo.setUpdateTime(date);
        // 调用dao
        int result = productDao.add(productVo);
        if (result > 0){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<Integer> modifyEnable(ProductVo productVo) {
        // 获取时间
        productVo.setUpdateTime(StringUtil.getStringDate());
        int result = productDao.modifyEnable(productVo);
        if (result > 0){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<Integer> deleteById(int id) {
        int result = productDao.deleteById(id);
        if (result > 0){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<ProductDto> findById(int id) {
        ProductDto productVo = productDao.findById(id);
        if (productVo != null){
            return ResultVo.success(productVo);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<Integer> update(ProductVo productVo) {
        // 获取时间
        productVo.setUpdateTime(StringUtil.getStringDate());
        // 调用dao
        int result = productDao.update(productVo);
        if (result > 0){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<Integer> deleteAll(Integer[] ids) {
        int[] ints = StringUtil.integersToInts(ids);
        int result = productDao.deleteAll(ints);
        if (result > 0){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<List<ProductDto>> getAll(FrontPageVo frontPageVo) {
        // 查出数据封装
        List<ProductDto> productList = productDao.getAll(frontPageVo);
        ResultVo<List<ProductDto>> resultVo = ResultVo.failed();
        if (productList != null){
            resultVo = ResultVo.success(productList);
            // 查出count
            resultVo.count(productDao.countEnable());
        }
        return resultVo;
    }

    @Override
    public ResultVo<List<ProductDto>> findByIdFront(int id) {
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        SetOperations<String, Object> opsForSet = redisTemplate.opsForSet();
        String ip = StringUtil.getIp();
        // 每个ip只能增加一次点击量
        // 拿到的这个ip不存在才增加点击量
        if (!opsForSet.members("userIp").contains("product:" + ip + ":" + id)){
            // 增加点击量
            opsForValue.increment("productVisits." + id);
            // 添加ip
            opsForSet.add("userIp" ,"product:" + ip + ":" + id);
        }
        List<ProductDto> productVo = productDao.findByIdFront(id);

        // 映射添加访问量
        List<ProductDto> collect = productVo.stream().map((productDto) -> {
            productDto.setVisits(opsForValue.get("productVisits." + id));
            return productDto;
        }).collect(Collectors.toList());

        if (productVo != null){
            return ResultVo.success(collect);
        }
        return ResultVo.failed();
    }
}
